-- Debug
-- 调试(错误处理)

function __traceback()
    local result = ""
    local level = 3
    local indent = ""
    while true do
        local info = debug.getinfo(level, "nSl")
        if not info then break end
        if info.what == "C" then   -- is a C function?
            result = string.format("%s\n%d C function", result, level-2)
        else   -- a Lua function
            result = string.format("%s\n%d %s() : <line:%d>",result, level-2, info.name or "???", info.currentline)
        end
        level = level + 1
        indent = indent .. "  "
    end
    return result
end

function __errorHandler(e)    
    __db = (e or "Error!") .. "\n" .. __traceback() .. "\n\n" .. "local variables:\n"
   
    --[[
    local a = 1
    while true do
        local name, value = debug.getlocal(2, a)
        if not name then break end
        if name ~= "(*temporary)" then
            __db = string.format("%s\n%s = %s", __db, name, tostring(value))
        end
        a = a + 1
    end
      ]]
    local a = 1
    while true do
        local name, value = debug.getlocal(2, a)
        if not name then break end
        if name ~= "(*temporary)" then
            if type(value) == "table" then
                local st = value
                value = tostring(st).."\n[["
                for k,v in pairs(st) do
                    value = string.format("%s\n %s = %s", value, tostring(k), tostring(v))
                end
                value = value.."\n]]"
            end
            __db = string.format("%s\n%s = %s", __db, name, tostring(value))
        end
        a = a + 1
    end
    displayMode(OVERLAY)
end

function __keyboard(key)
    if true then
        if key == "\n" then
            if buffer == "quit" then
                showConsole = false
            elseif buffer == "restart" then
                restart()
            elseif buffer == "debug" then
                displayMode(OVERLAY)
            else
                pcall(loadstring(buffer))
            end
            buffer = ""
        elseif key == BACKSPACE then
            if string.len(buffer) > 0 then
                buffer = string.sub(buffer, 1, string.len(buffer)-1)    
            end    
        else
            buffer = buffer .. key
        end
    end
end

function res()
    __paused = false  
    __db = ""
end

function DebugInit()
    parameter.boolean("showConsole",false)
    __draw = draw
    __touched = touched
    __db = ""
    __paused = false
    __showingConsole = false
    buffer = ""
    parameter.watch("__db")
    parameter.action("restart running",function() res() displayMode(FULLSCREEN) end)
    draw = function()
        if __paused == false then
            local status, err = xpcall(__draw, __errorHandler)
            if status == false then
                __paused = true
                showConsole = true
            end
        else
            background(0, 0, 0, 255)
        end
        if showConsole == true and __showingConsole == false then
            __showingConsole = true
            __oldKB = keyboard
            keyboard = __keyboard
            showKeyboard()
        elseif showConsole == false and __showingConsole == true then
            __showingConsole = false
            hideKeyboard()
            keyboard = __oldKB
        end
        if not isKeyboardShowing() and showConsole then
            showConsole = false
        end
        if __showingConsole then
            noStroke()
            rectMode(CORNER)
            fill(0, 0, 0, 180)
            rect(0,0,WIDTH,HEIGHT)
            font("Inconsolata")
            fontSize(ConsoleFontSize)
            textAlign(LEFT)
            textMode(CORNER)
            textWrapWidth(WIDTH - 10)
            fill(255, 255, 255, 255)
            local str = "Console 指令输入工具\n:> " .. buffer
            local _,h = textSize(str)
            text(str, 5, HEIGHT - h - 5)
        end
    end
    touched = function(touch)
        if __paused == false then
            local status, err = xpcall(function() __touched(touch) end, __errorHandler)
            if status == false then
                __paused = true             
                showConsole = true
            end
        end
    end
end